﻿using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Net;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;

namespace TiktokAcquisition
{
    public class HttpHelper
    {
        private readonly HttpClient _httpClient;
        private static readonly TimeSpan DefaultTimeout = TimeSpan.FromSeconds(30);


        /// <summary>
        /// 初始化HttpHelper
        /// </summary>
        /// <param name="baseAddress">基础地址(可选)</param>
        /// <param name="timeout">超时时间(默认30秒)</param>
        public HttpHelper(string baseAddress = null, TimeSpan? timeout = null)
        {
            _httpClient = new HttpClient(new HttpClientHandler
            {
                AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate
            });

            if (!string.IsNullOrEmpty(baseAddress))
            {
                _httpClient.BaseAddress = new Uri(baseAddress);
            }

            _httpClient.Timeout = timeout ?? DefaultTimeout;

            // 默认请求头
            _httpClient.DefaultRequestHeaders.Add("Accept", "application/json");
            _httpClient.DefaultRequestHeaders.Add("User-Agent", "HttpHelper");
        }

        /// <summary>
        /// 发送GET请求
        /// </summary>
        /// <param name="url">请求地址</param>
        /// <param name="headers">自定义请求头</param>
        /// <returns>响应字符串</returns>
        public async Task<string> GetAsync(string url, Dictionary<string, string> headers = null)
        {
            if (string.IsNullOrWhiteSpace(url))
            {
                throw new ArgumentNullException(nameof(url));
            }

            using (var request = new HttpRequestMessage(HttpMethod.Get, url))
            {
                AddHeaders(request, headers);

                var response = await _httpClient.SendAsync(request);
                response.EnsureSuccessStatusCode();

                return await response.Content.ReadAsStringAsync();
            }
        }

        /// <summary>
        /// 发送GET请求并返回指定类型
        /// </summary>
        /// <typeparam name="T">返回类型</typeparam>
        /// <param name="url">请求地址</param>
        /// <param name="headers">自定义请求头</param>
        /// <returns>响应对象</returns>
        public async Task<T> GetAsync<T>(string url, Dictionary<string, string> headers = null)
        {
            var response = await GetAsync(url, headers);
            return JsonConvert.DeserializeObject<T>(response);
        }

        /// <summary>
        /// 发送POST请求
        /// </summary>
        /// <param name="url">请求地址</param>
        /// <param name="data">请求数据</param>
        /// <param name="headers">自定义请求头</param>
        /// <param name="contentType">内容类型(默认application/json)</param>
        /// <returns>响应字符串</returns>
        public async Task<string> PostAsync(string url, object data = null, Dictionary<string, string> headers = null, string contentType = "application/json")
        {
            if (string.IsNullOrWhiteSpace(url))
            {
                throw new ArgumentNullException(nameof(url));
            }

            using (var request = new HttpRequestMessage(HttpMethod.Post, url))
            {
                AddHeaders(request, headers);

                if (data != null)
                {
                    var content = data is string str
                        ? new StringContent(str, Encoding.UTF8, contentType)
                        : new StringContent(JsonConvert.SerializeObject(data), Encoding.UTF8, contentType);

                    request.Content = content;
                }

                var response = await _httpClient.SendAsync(request);
                response.EnsureSuccessStatusCode();

                return await response.Content.ReadAsStringAsync();
            }
        }

        /// <summary>
        /// 发送POST请求并返回指定类型
        /// </summary>
        /// <typeparam name="T">返回类型</typeparam>
        /// <param name="url">请求地址</param>
        /// <param name="data">请求数据</param>
        /// <param name="headers">自定义请求头</param>
        /// <param name="contentType">内容类型(默认application/json)</param>
        /// <returns>响应对象</returns>
        public async Task<T> PostAsync<T>(string url, object data = null, Dictionary<string, string> headers = null, string contentType = "application/json")
        {
            var response = await PostAsync(url, data, headers, contentType);
            return JsonConvert.DeserializeObject<T>(response);
        }

        /// <summary>
        /// 添加请求头
        /// </summary>
        private void AddHeaders(HttpRequestMessage request, Dictionary<string, string> headers)
        {
            if (headers != null)
            {
                foreach (var header in headers)
                {
                    request.Headers.Add(header.Key, header.Value);
                }
            }
        }

        /// <summary>
        /// 释放资源
        /// </summary>
        public void Dispose()
        {
            _httpClient?.Dispose();
        }
    }
}
